from importlib import import_module
from Spider.util.Base import BaseMiddleware
from Spider.settings import DOWNLOADER_MIDDLEWARE
from Spider.util.MyFuncClass import HttpRequest, HttpResponse
from Spider.Exception.exceptions import ClassNotFound, InheritError, ObjectTypeError


class Handle(object):
    def __init__(self):
        self.dict = DOWNLOADER_MIDDLEWARE

    def get_list(self, flag):
        return sorted(self.dict, key=lambda keys: self.dict.get(keys), reverse=flag)
    
    def process_middleware(self, middleware_list, request, response=None):
        for middleware in middleware_list:
            lis = middleware.split('.')
            module_path = '.'.join(lis[:-1])
            cls_name = lis[-1]
            module = import_module(module_path)
            if hasattr(module, cls_name):
                cls = getattr(module, cls_name)
                if issubclass(cls, BaseMiddleware):
                    o = cls()
                    if response is None:
                        request = o.process_request(request)
                        if not isinstance(request, HttpRequest):
                            raise ObjectTypeError('process_request must return HttpRequest')
                    else:
                        response = o.process_response(request, response)
                        if isinstance(response, HttpRequest):
                            break
                        if not (isinstance(response, HttpRequest) or isinstance(response, HttpResponse)):
                            raise ObjectTypeError('process_response must return HttpRequest or HttpResponse')  
                else:
                    raise InheritError('This ' + cls_name + ' must inherit BaseMiddleware')
            else:
                raise ClassNotFound('This ' + cls_name + ' is not found in ' + module_path)
        if response is None:
            return request
        else:
            return response

    def request_ware(self, request):
        
        return self.process_middleware(self.get_list(flag=False), request)

    def response_ware(self, request, response):
        
        return self.process_middleware(self.get_list(flag=True), request, response)
